﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Linq;

namespace SStuff.FlowControls
{
    /// <summary>
    /// Provides helper methods for the Visual tree
    /// </summary>
    public static class VisualTreeHelperEx
    {
        /// <summary>
        /// Defines if the specified element is inside the specified visual tree
        /// </summary>
        /// <param name="element"></param>
        /// <param name="treeRoot"></param>
        /// <returns></returns>
        public static bool IsInVisualTree(this DependencyObject element, DependencyObject treeRoot)
        {
            return element.GetVisualAncestors().Contains(treeRoot);
        }

        /// <summary>
        /// Indicates if the specified element is in the main Visual Tree
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        public static bool IsInMainVisualTree(this DependencyObject element)
        {
#if SILVERLIGHT
            return IsInVisualTree(element, Application.Current.RootVisual);
#else
            return element.GetVisualAncestors().LastOrDefault() is Window;
#endif
        }

        /// <summary>
        /// Get visual ancestors of the specified element
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        public static IEnumerable<DependencyObject> GetVisualAncestors(this DependencyObject element)
        {
            DependencyObject candidate = null;
            while (element != null)
            {
                candidate = VisualTreeHelper.GetParent(element);
                if (candidate == null)
                {
                    var asFe = element as FrameworkElement;
                    if (asFe != null)
                        candidate = asFe.Parent;
                }
                element = candidate;
                if (element != null)
                    yield return element;
            }

        }

        public static IEnumerable<DependencyObject> GetVisualDescendants(this DependencyObject element)
        {
            int childCount = VisualTreeHelper.GetChildrenCount(element);
            for(int i=0; i<childCount;i++)
            {
                var child = VisualTreeHelper.GetChild(element, i);
                yield return child;
                foreach (var descendant in child.GetVisualDescendants())
                {
                    yield return descendant;
                }
            }
        }
    }
}
